<?php

namespace app\api\controller;

use app\api\model\SeparateSet;
use app\api\model\WechatLog;
use app\common\controller\Api;
use think\cache\driver\Redis;
use wechat\WechatController;
use think\Request;
/**
 * 微信分账接口
 */
class SeparateAccounts extends Api
{
    private static string $sign_str = '_yoko';
    protected $noNeedLogin = '*';
    protected $noNeedRight = '*';// 允许调用接口的渠道
    protected $noSign = ['callback', 'notify']; // 参与签名
    /**
     * @var array|mixed
     */
    private $params;
    private WechatController $wechat;
    private \app\api\model\SeparateAccounts $model;
    private Redis $redis;
    private SeparateSet $secret;

    /**
     * @var array|mixed
     */
    public function __construct(Request $request = null)
    {
        parent::__construct($request);
        $this->redis = new Redis();
        $this->params = $this->request->param();
        $action = $this->request->action();
        $this->model = new \app\api\model\SeparateAccounts();
        if (!in_array($action, $this->noSign)) {
            $this->checkSign();
            $sub_mch_id = $this->params['params']['sub_mch_id'];
            $this->wechat = new WechatController($sub_mch_id,$this->secret);
        }
    }

    private function checkSign()
    {
        $data = $this->request->param();
        if (empty($data['secret']) || empty($data['sign'])) {
            $this->error("[secret/sign]参数缺失");
        }
        $this->secret = SeparateSet::get(['secret'=>$data['secret']]);
        if(empty($this->secret->state) || $this->secret->state != 1)
            $this->error("该渠道已被关闭");
        if (empty($data['params']['sub_mch_id'])) {
            $this->error("sub_mch_id参数缺失");
        }
        // 过滤可选参数 目前只允许数钱游戏
        $user_str = $data['params']['sub_mch_id'] . self::$sign_str;
        sort($data['params']);
        $sign = md5(implode("&", $data['params']) . "&" . $user_str);
//        if ($data['sign'] != $sign) {
//            $this->error("签名错误");
//        }
    }

    public function payment()
    {
        $param = $this->params['params'];
        $redis_key = "payment:".$param['order_id'];
        $res = $this->redis->get($redis_key);
        if (!empty($res)){
            $res = json_decode($res,true);
            $this->success("获取成功",$res['data']);
        }
        $res = $this->wechat->unifiedorder($param);
        if ($res['result_code'] == 'FAIL') {
            $this->error($res['result_message']);
        }
        // 这里插入数据库
        $param['service_secret'] = $this->params['secret'];
        $param['return_data'] = json_encode($res['data']);
        $param['other_order'] = date("YmdHis") . mt_rand(100000, 999999);
        $res['data']['other_order'] = $param['other_order'];
        $this->redis->set("payment:".$param['order_id'],
            json_encode($res,JSON_UNESCAPED_UNICODE),3600);
        $this->model::create($param);
        // end
        $this->success("获取成功", $res['data']);
    }

    // 发起支付
    public function callback()
    {
        $xml = Request::instance()->getContent();
        $data = $this->xmlToArray($xml);
        $this->redis->set('callback', $data);
        //$data = $redis->get('wxnotify');
        if (!empty($data)) {
            $exits = WechatLog::get(['out_trade_no' => $data['out_trade_no']]);
            if (empty($exits)) {
                // 这里先写表 防止后续代码进行不下去
                WechatLog::create($data);
            }
        }
        $this->secret = SeparateSet::get(['mch_id'=>$data['mch_id']]);
        $this->wechat = new WechatController($data['sub_mch_id'],$this->secret);
        $res = $this->wechat->handlePaidNotify($data);
        $xml = "<xml>
              <return_code><![CDATA[FAIL]]></return_code>
              <return_msg><![CDATA[NO]]></return_msg>
            </xml>";
        if ($res['result_code'] == 'SUCCESS') {
            $xml = "<xml>
                  <return_code><![CDATA[SUCCESS]]></return_code>
                  <return_msg><![CDATA[OK]]></return_msg>
                </xml>";
        }
        // 返回带自定义根节点的 XML 数据
        return response($xml, '200');
    }

    // 支付回调
    private function xmlToArray($xml)
    {
        if (!$xml) {
            return [];
        }
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        foreach ($data as &$datum) {
            $datum = trim($datum);
        }
        return $data;
    }

    // 开启分账
    public function notify()
    {
        $xml = Request::instance()->getContent();
        $data = $this->xmlToArray($xml);
//        $data = $this->redis->get('notify');
        $this->redis->set('notify',$data);
        if (!empty($data)) {
            $exits = WechatLog::get(['out_trade_no' => $data['out_trade_no']]);
            if (empty($exits)) {
                // 这里先写表 防止后续代码进行不下去
                WechatLog::create($data);
            }
        }
        
        $this->secret = SeparateSet::get(['mch_id'=>$data['mch_id']]);
        $this->wechat = new WechatController($data['sub_mch_id'],$this->secret);
        $res = $this->wechat->notify($data);
        $xml = "<xml>
              <return_code><![CDATA[FAIL]]></return_code>
              <return_msg><![CDATA[NO]]></return_msg>
            </xml>";
        if ($res['result_code'] == 'SUCCESS') {
            $this->mch_share(['out_trade_no' => $data['out_trade_no'], 'sub_mch_id' => $data['sub_mch_id'],
                'transaction_id'=>$data['transaction_id']]);
            $xml = "<xml>
                  <return_code><![CDATA[SUCCESS]]></return_code>
                  <return_msg><![CDATA[OK]]></return_msg>
                </xml>";
        }
        // 返回带自定义根节点的 XML 数据
        return response($xml, '200');
    }

    public function mch_share($params)
    {
        $redis = new Redis();
        $redis->set('share', $params);
        $res = $this->wechat->share($params);
        if ($res['result_code'] == 'FAIL') {
            $this->error($res['result_message']);
        } else {
            $this->success($res['result_code']);
        }
    }

    // 测试支付
    public function share()
    {
        $params = $this->params['params'];
        $this->redis->set('share', $params);
//        $params = $this->redis->get('share');
        $res = $this->wechat->share($params);
        if ($res['result_code'] == 'FAIL') {
            $this->error($res['result_message']);
        } else {
            $this->success($res['result_code']);
        }
    }
}